<template>
  <ul class="right-menu" :class="customClass" @click.stop="() => {}">
    <!-- 循环菜单项，事件带参数抛出 -->
    <li
      v-for="(item, i) in options"
      :key="item.label + i"
      class="right-menu-item"
      :class="{ 'is-disabled': item.disabled }"
      @click.stop="handleClick($event, item)"
    >
      <div class="right-menu-item-btn">
        <!-- 图标和按钮名 -->
        <i :class="item.icon" class="iii" />
        <span>{{ item.label }}</span>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'ContextMenu',
  props: {
    // 右键点击的位置
    position: {
      type: Object,
      default: () => ({
        x: 0,
        y: 0
      })
    },
    // 菜单列表
    options: {
      type: Array,
      default: () => ([])
    },
    // 重要参数，用于标识是哪个右键菜单dom元素
    classIndex: {
      type: Number,
      default: 0
    },
    // 自定义菜单class
    customClass: {
      type: String,
      default: ''
    }
  },
  watch: {
    // 监听右键点击时点击位置的变化，只要变化了，就弹出右键菜单供用户点击操作
    position: {
      handler () {
        this.show()
      },
      deep: true
    }
  },
  methods: {
    show () {
      const { x, y } = this.position
      const innerWidth = window.innerWidth // 获取页面可视区域宽度，即页面的宽度
      const innerHeight = window.innerHeight // 获取可视区域高度，即页面的高度
      /**
       * 注意，这里要使用getElementsByClassName去选中对应dom，因为右键菜单组件可能被多处使用
       * classIndex标识就是去找到对应的那个右键菜单组件的，需要加的
       * */
      const menu = document.getElementsByClassName('right-menu')[this.classIndex]
      menu.style.display = 'block'
      const menuHeight = menu.offsetHeight // 菜单容器高
      const menuWidth = menu.offsetWidth // 菜单容器宽
      // 菜单的位置计算
      menu.style.top =
        (y + menuHeight > innerHeight ? y - menuHeight : y) + 'px'
      menu.style.left =
        (x + menuWidth > innerWidth ? x - menuWidth : x) + 'px'
      // 因为菜单还要关闭，就绑定一个鼠标点击事件，通过e.button判断点击的是否是左键，左键关闭菜单
      document.body.addEventListener('click', this.hide)
    },
    hide (e) {
      if (e.button === 0) {
        // 0是左键、1是滚轮按钮或中间按钮（若有）、2鼠标右键
        const menu = document.getElementsByClassName('right-menu')[this.classIndex] // 同样的精确查找
        menu.style.display = 'none' // 菜单关闭
        document.body.removeEventListener('click', this.hide) // 及时解绑监听事件
      }
    },
    handleClick (e, item) {
      this.$emit('select', item)
      this.hide(e)
    }
  }
}
</script>

<style lang='scss' scoped>
.right-menu {
  border: 1px solid rgba(0,0,0,.1);
  color: #333;
  background: #fff;
  border-radius: 4px;
  list-style-type: none;
  box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
  font-size: 14px;
  font-weight: 500;
  box-sizing: border-box;
  padding: 4px 0;
  // 固定定位，抬高层级，初始隐藏，右击时置为display:block显示
  position: fixed;
  z-index: 3000;
  display: none;
}
.right-menu-item {
  height: 30px;
  line-height: 30px;
  margin: 4px 0;
  padding: 0 16px;
  overflow: hidden;
  font-size: 14px;
  text-overflow: ellipsis;
  transition: all 0.36s;
  cursor: pointer;
  .right-menu-item-btn {
    .iii {
      margin-right: 4px;
    }
  }
}
.right-menu-item:hover {
  background-color: #ebf5ff;
  color: #6bacf2;
}
.right-menu-item.is-disabled {
  opacity: .25;
  cursor: not-allowed;
  pointer-events: none;
  background: none!important;
}
</style>
